home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / GRAPHICS / DEVEL2.ZIP / DEVEL2.DOC < prev    next >
Encoding:
Text File  |  1992-04-24  |  31.4 KB  |  746 lines

  1.  
  2.       REND386 -- A 3-D Polygon Rendering Package for the 386 and 486
  3.                   Written by Dave Stampe and Bernie Roehl
  4.  
  5.                            LIBRARY Documentation
  6.                          Version 2.02 - April 1992
  7.  
  8. This package contains a library of routines (callable from C) that will
  9. render 3 dimensional scenes on 386 and 486 based systems with a VGA display.
  10.  
  11. The package also includes a simple user-interface library with joystick
  12. support, and a demo program to show what it's capabable of.
  13.  
  14. The package is designed to be fast.   It accomplishes that goal by making
  15. use of the special instructions that exist only on 386 and 486 processors;
  16. it will not run on 286s, 8086s or 8088s.
  17.  
  18. It also requires Turbo C++ or Borland C to link; Turbo C 2.00 seems to
  19. generate unresolved references.
  20.  
  21. A NOTE ON SPEED:
  22.  
  23. Speed is not a straightforward thing to measure.  There is a relationship
  24. between the speed of the processor, the complexity of the scene, and the
  25. number of frames per second.
  26.  
  27. With this software, a 512-polygon scene can be rendered at speeds up to
  28. 14 frames/second on a 486/25; this corresponds to a speed of over 7000
  29. polys/second.
  30.  
  31. LICENSING:
  32.  
  33. These libraries may be freely used to write software for release into the
  34. public domain.  Permission to use these libraries for the production of
  35. commercial software (including shareware) must be obtained from the authors,
  36. Bernie Roehl (broehl@sunee.uwaterloo.ca) and Dave Stampe
  37. (dstampe@sunee.uwaterloo.ca).
  38.  
  39. Licensing terms will be very, very reasonable.
  40.  
  41. SOFTWARE DOCUMENTATION
  42.  
  43. The following sessions describe the various data structures and routines
  44. that comprise the rend386 package.
  45.  
  46. SECTION A -- OBJECTS
  47.  
  48. The following functions deal with OBJECTs.  OBJECTs have several properties
  49. associated with them: a set of vertices, a set of polygons, a name, an
  50. owner and a set of flags.  Each vertex has an x,y,z location in the object's
  51. native coordinates, and a (probably different) x,y,z location in world
  52. coordinates.  Each polygon has a color value and an array of pointers to the
  53. vertices that define that polygon.
  54.  
  55. OBJECT *new_obj(int type, int nv, int np, char *name)
  56.          Creates a new object, with room for up to nv vertices and np polygons.
  57.          The given name is set in the object.
  58.  
  59. void add_vertex(OBJECT *obj, long x, long y, long z)
  60.          Adds a vertex to the given object, with x,y,z as its coordinates
  61.          in object space.
  62.  
  63. POLY *add_poly(OBJECT *obj, unsigned color, int npoints)
  64.          Adds a polygon to the given object, with the given color and room
  65.          for up to npoints vertices.
  66.  
  67. void add_point(OBJECT *obj, POLY *p, int vertnum)
  68.          Adds a point to a polygon.  Vertex number vertnum in object obj is
  69.          added to the given polygon.  The vertices must be added in a
  70.          "clockwise" order as seen from outside the object.
  71.  
  72. void delete_obj(OBJECT *obj)
  73.          Deletes the given object and frees all memory associated with it.
  74.  
  75. long object_bounds(OBJECT *obj, long *x, long *y, long *z)
  76.          Obtains the x,y,z extents of the given object.
  77.  
  78. void compute_obj(OBJECT *obj)
  79.          Does internal computation of polygon normals, bounding sphere, and
  80.          so forth.  Must be called once the object is complete (i.e. all the
  81.          vertices and polygons have been added, and the points comprising
  82.          the polys have been defined) and before the object is rendered.
  83.  
  84. void set_obj_flags(OBJECT *obj, unsigned char value)
  85.          Sets the object's flags.
  86.  
  87. unsigned char get_obj_flags(OBJECT *obj)
  88.          Gets the object flags.
  89.  
  90. The bottom two bits of the flags word are named OBJ_INVIS (which indicates
  91. that the object is invisible and should not be drawn) and OBJ_HIGHLIGHTED
  92. (indicating that the object should be drawn highlighted).
  93.  
  94. void get_obj_info(OBJECT *obj, int *nv, int *np, char *buffer, int maxn)
  95.         Extracts the number of vertices in obj and stores it in *nv, and
  96.         similarly stores the number of polys in obj in *np.  If maxn is
  97.         non-zero, the given buffer is filled in with the name of the object
  98.         (if one has been set).  The buffer must contain room for up to maxn
  99.         characters.
  100.  
  101. void get_vertex_info(OBJECT *obj, int vertnum, long *x, long *y, long *z)
  102.         Extracts the x, y and z values of vertex number vertnum in obj.
  103.         This function obtains the coordinates in the object coordinate system.
  104.  
  105. void get_vertex_world_info(OBJECT *obj, int vertnum, long *x, long *y, long *z)
  106.         Extracts the x, y and z values of vertex number vertnum in obj.
  107.         This function obtains the coordinates in the world coordinate system.
  108.  
  109. void get_poly_info(OBJECT *obj, int polynum, unsigned *color, int *nverts,
  110.    int *verts, int maxverts)
  111.         Extracts information from polygon number polynum in obj.  The color
  112.         parameter is set to the polygon color (see colors.doc for details).
  113.         If maxverts is non-zero, then the array of integers verts is filled
  114.         in with the index numbers of the vertices comprising the polygon.
  115.         No more than maxverts vertices will be stored; if there are more
  116.         than that number of vertices in the object, the rest will be ignored.
  117.  
  118. void set_poly_color(OBJECT *obj, int polynum, unsigned color)
  119.         Sets the color of polygon number polynum in obj to the given color.
  120.         See colors.doc for details of how the color parameter is interpreted.
  121.  
  122. void *get_object_owner(OBJECT *obj)
  123.         Returns the owner field of the given object.  The owner field is not
  124.         used by the renderer, and is provided for the convenience of the
  125.         application programmer.  It might, for example, be a pointer to the
  126.         segment that this object is the representation of (see the section on
  127.         segments for more information).
  128.  
  129. void set_object_owner(OBJECT *obj, void *owner)
  130.         Sets the object's owner field.
  131.  
  132. OBJECT *copy_obj(OBJECT *obj, int nverts, int npolys, char *name)
  133.         Makes a copy of the given object, with room for nverts vertices and
  134.         npolys polygons.  This is to allow you to add additional vertices
  135.         and polygons using an existing object as a starting point.  The name
  136.         field is set in the copy.
  137.  
  138. void copy_world_to_object(OBJECT *obj)
  139.         Copies the world coordinates of the object into its object coordinates,
  140.         effectively making the object's coordinate system the same as the
  141.         world coordinate system.  Rarely used.
  142.  
  143. void highlight_obj(OBJECT *obj)
  144.         Turns on the HIGHLIGHT bit in the color field of all the polys in the
  145.         given object.
  146.  
  147. void unhighlight_obj(OBJECT *obj)
  148.         Turns off the HIGHLIGHT bit in the color field of all the polys in the
  149.         given object.
  150.  
  151. SECTION B -- OBJLISTS
  152.  
  153. The following functions deal with object lists, or OBJLISTs.  An OBJLIST is
  154. what you pass to the renderer (i.e. you tell it to render a given list of
  155. objects).
  156.  
  157. OBJLIST *new_objlist()
  158.         Creates a new object list and returns a pointer to it.
  159.  
  160. void add_to_objlist(OBJLIST *list, OBJECT *obj)
  161.         Adds an object to an object list.
  162.  
  163. void remove_from_objlist(OBJLIST *list, OBJECT *obj)
  164.         Removes an object from an object list.
  165.  
  166. void del_objlist(OBJLIST *list)
  167.         Deletes an object list.
  168.  
  169. OBJECT *first_in_objlist(OBJECT **objlist)
  170.         Returns a pointer to the first object in a list.
  171.  
  172. OBJECT *next_in_objlist(OBJECT **objlist, OBJECT *obj)
  173.         Returns a pointer to the next object (after obj) in a list.
  174.  
  175. OBJECT *prev_in_objlist(OBJECT **objlist, OBJECT *obj)
  176.         Returns a pointer to the previous object (after obj) in a list.
  177.  
  178. int is_first_in_objlist(OBJECT **objlist, OBJECT *obj)
  179.         Returns non-zero if obj is the first entry in the given list.
  180.  
  181. int is_last_in_objlist(OBJECT **objlist, OBJECT *obj)
  182.         Returns non-zero if obj is the last entry in the given list.
  183.  
  184. SECTION C -- VIEWS
  185.  
  186. In addition to an OBJLIST, the rendering routines need to know about your
  187. current viewpoint; the VIEW structure contains this information.  It has
  188. three fields (ex, ey, ez) that define the current location of your "eye"
  189. or "camera" in world coordinates, and another three (pan, tilt and roll)
  190. that define the "camera's" rotation about the Y (vertical) axis, X
  191. (horizontal) axis, and Z (forward) axis respectively.
  192.  
  193. The VIEW also has near/far clipping information in the the hither and yon
  194. fields (in world coordinates).
  195.  
  196. (A note about coordinates: X is positive to the right, Y is positive up and
  197. Z is positive away from you).
  198.  
  199. There is also a zoom factor, which works like the zoom on a camera.
  200.  
  201. The angles and zoom factor are all stored as 32-bit (long) integers, but
  202. are best thought of as floating point numbers multiplied by 65536L.  This
  203. is referred to in this document as "16.16" format (16 bits of integer,
  204. 16 bits of fraction).
  205.  
  206. A VIEW also has information about what area on the screen should be used to
  207. present the scene; these left, right, top and bottom values are in absolute
  208. screen coordinates.  There is also an "aspect ratio" which determines the
  209. relative size of a non-square pixel.
  210.  
  211. The world-space coordinates of a single light source are stored in the lx,ly
  212. an lz fields.
  213.  
  214. There is also a "flags" field whose bottom bit is set if the objects should
  215. all be drawn in wire-frame mode rather than as filled polygons.  Because no
  216. explicit edge information is stored in the OBJECT data structures, wireframing
  217. is actually slower than filled-polys since each edges winds up getting drawn
  218. twice.
  219.  
  220. The next two bits (called HIDE_HIGHLIGHTED and HIDE_UNHIGHLIGHTED) determine
  221. whether highlighted (and/or unhighlighted) objects should be invisible.
  222.  
  223. Finally, there's a 200 byte "work area" associated with each VIEW.
  224.  
  225. void compute_view_factors(VIEW *v)
  226.    This function should be called whenever the view has changed; it
  227.    computes internal information based on the values described above.
  228.  
  229. In addition to all this, there's a global struct called Screeninfo that
  230. has the minimum and maximum X and Y values, the number of available colors,
  231. the number of pages, and the screen coordinates of the screen "center".
  232.  
  233. SECTION D -- MATRICES
  234.  
  235. A matrix is a 4 by 3 array of long (32-bit) integers.  It can best be thought
  236. of as an upper 3x3 matrix representing rotations, and 3-element bottom row
  237. vector representing translation.  A matrix is used to transform a point or
  238. an object.
  239.  
  240. void make_matrix(MATRIX m, long rx, long ry, long rz, long tx, long ty, long tz)
  241.    Fills in a matrix with the appropriate values for rotation and translation.
  242.    The rx, ry and rz values are the rotations around the three axes; these
  243.    values are all in 16.16 format (i.e. a 16-bit integer part and a 16-bit
  244.    fractional part) and are expressed in degrees.  To convert from degrees in
  245.    floating-point to this format, just multiply by 65536L.  The translation
  246.    values tx, ty and tz are all in 32-bit "world" units.
  247.  
  248. void matrix_mult(MATRIX a, MATRIX b, MATRIX c)
  249.    Does a pseudo-matrix-multiply.  The 'a' matrix is multiplied by the 'b'
  250.    matrix and the result is stored in the 'c' matrix.  Note that this is not
  251.    a real matrix multiply; only the top 3x3 matrix is affected.  You must deal
  252.    with the bottom 3-element vector separately.
  253.  
  254. void matrix_point(MATRIX m, long *xp, long *yp, long *zp)
  255.    Applies the given matrix to a point given the addresses of its x,y,z values.
  256.  
  257. void apply_matrix(OBJECT *obj, MATRIX m)
  258.    Applies the given matrix to all the vertices in the given object,
  259.    generating new world coordinates from the object coordinates.
  260.  
  261. void matrix_transpose(MATRIX a, MATRIX b)
  262.    Transposes the matrix 'a' into the matrix 'b' (exchanges rows with columns).
  263.  
  264. void inverse_matrix(MATRIX a, MATRIX b)
  265.    Finds the pseudo-inverse of 'a' and stores it in 'b'.  This is not a real
  266.    inverse; it only works for matrices in which the top 3x3 is a rotation
  267.    submatrix and the bottom row is a translation vector.
  268.  
  269. long isine(long angle)
  270.    Returns the sine of the angle in internal format; the angle is in degrees,
  271.    in 16.16 format.  Probably does not need to be called directly.
  272.  
  273. long icosine(long angle)
  274.    Returns the cosine of the angle in internal format; the angle is in degrees,
  275.    in 16.16 format.  Probably does not need to be called directly.
  276.  
  277. SECTION E -- SEGMENTS
  278.  
  279. A segment is a piece of an articulated (multi-jointed) figure.  Each segment
  280. has a parent segment; the parent the "root" segment is NULL.  Each segment
  281. has a linked list of children, and each segment has a 'sibling' which
  282. is the next segment in the parent's linked list of children.
  283.  
  284. Each segment also has several values associated with it, including the
  285. position and orientation of the segment relative to its parent (or relative
  286. to the world coordinate system, for the root object) as well as a name and
  287. a "representation" which might, for example, be a pointer to an OBJECT.
  288.  
  289. SEGMENT *new_seg(SEGMENT *parent)
  290.       Creates a new segment, with the given segment as its parent.  If the
  291.       'parent' parameter is NULL, this is a root object.
  292.  
  293. void seg_setrep(SEGMENT *s, void *rep)
  294.       Sets the 'representation' field of the given segment to the given value.
  295.   
  296. void *seg_getrep(SEGMENT *s)
  297.       Returns the value of the 'representation' field of the given segment.
  298.  
  299. void seg_getposition(SEGMENT *s, long *x, long *y, long *z, long *rx,
  300.   long *ry, long *rz)
  301.       Stores the current position of the given segment (relative to its parent)
  302.       in *x, *y and *z; also stores its orientation (in 16.16 format) in *rx,
  303.       *ry and *rz.
  304.  
  305. char *seg_getname(SEGMENT *s)
  306.       Returns the name of the given segment.
  307.  
  308. void set_setname(SEGMENT *s, char *name)
  309.       Sets the name of the given segment to the given value; a copy is made.
  310.  
  311. void rel_move_segment(SEGMENT *obj, long x, long y, long z)
  312.       Performs a relative move of the given segment; x, y and z are the amounts
  313.       to move the segment along each of the three axes.  After calling this
  314.       routine, you must at some point call update_segment().
  315.  
  316. void abs_move_segment(SEGMENT *obj, long x, long y, long z)
  317.       Performs an absolute move of the given segment; x, y and z are the new
  318.       to move the segment along each of the three axes.  After calling this
  319.       routine, you must at some point call update_segment().
  320.  
  321. void rel_rot_segment(SEGMENT *seg, long rx, long ry, long rz)
  322.       Performs a relative rotation of the given segment; x, y and z are the
  323.       angles to rotate the segment along each of the three axes (in 16.16
  324.       format).  After calling this routine, you must at some point call
  325.       update_segment().
  326.  
  327. void abs_rot_segment(SEGMENT *seg, long rx, long ry, long rz)
  328.       Performs an absolute rotation of the given segment; x, y and z are the
  329.       angles to rotate the segment to along each of the three axes (in 16.16
  330.       format).  After calling this routine, you must at some point call
  331.       update_segment().
  332.  
  333. void update_segment(SEGMENT *s)
  334.       Takes the current position and orientation and uses it (and similar
  335.       information from the parent segment, and its parents, and so on) to
  336.       transform the segment's representation.
  337.  
  338. SEGMENT *find_root_segment(SEGMENT *s)
  339.       Walks up the tree from the given segment and finds the root segment for
  340.       the figure of which the segment is a part.
  341.  
  342. SEGMENT *parent_segment(SEGMENT *s)
  343.       Returns the parent of the given segment.
  344.  
  345. SEGMENT *child_segment(SEGMENT *s)
  346.       Returns the child of the given segment.
  347.  
  348. SEGMENT *sibling_segment(SEGMENT *s)
  349.       Returns the sibling of the given segment.
  350.  
  351. SEGMENT *copy_segment(SEGMENT *s, long dx, long dy, long dz,
  352.   void *(*copyrep_fn)())
  353.       Makes a copy of the given segment, displaced from the original by
  354.       dx,dy,dz, and uses the given function (if not NULL) to make a copy
  355.       of the original segment's representation and set it as the
  356.       representation of the copy.  A pointer to the new segment is returned.
  357.  
  358. void delete_segment(SEGMENT *s, void (*delrep_fn)())
  359.       Deletes the given segment and frees the memory associated with it; calls
  360.       the given function (if not NULL) to delete any representation associated
  361.       with the given segment.
  362.  
  363. void attach_segment(SEGMENT *s, SEGMENT *to)
  364.       Attaches the given segment to the given parent ('to'), making it a child
  365.       of that segment.
  366.  
  367. void detach_segment(SEGMENT *s)
  368.       Detaches the given segment from its parent, and makes it an independent
  369.       segment with no parent.  Its children remain attached to it, and other
  370.       siblings are unaffected (i.e. they still descend from the same parent
  371.       that has 'disowned' the given segment).
  372.  
  373. void seg_set_load_info(SEGMENT *s, char *filename, float sx, float sy,
  374.   float sz, long tx, long ty, long tz)
  375.       Stores the information about the scaling and translation of a loaded
  376.       representation into the SEGMENT struct; this is so we can get it back
  377.       later when it comes time to write the segment information back out to
  378.       a file again.
  379.  
  380. char *seg_get_load_info(SEGMENT *s, float *sx, float *sy, float *sz, long *tx,
  381.   long *ty, long *tz)
  382.       Retrieves the scaling and translation of a loaded representation from the
  383.       SEGMENT struct, so we can write it out to a file.
  384.  
  385. SECTION F -- COLORS
  386.  
  387. Four integers are defined in color16.c or color256.c; they are as follows:
  388.  
  389.   screen_clear_color -- the color to which the screen should be cleared
  390.   wireframe_color    -- the color in which to draw wireframe outlines
  391.   highlight_color    -- the color in which to highlight (outline) objects
  392.   highest_color      -- the highest color available in this mode (15 or 255)
  393.  
  394. They can be changed in the appropriate colors file to whatever values you
  395. choose.
  396.  
  397. Color-related routines are as follows:
  398.  
  399. set_colors()
  400.       Sets up (initializes) the palette.
  401.  
  402. reset_colors()
  403.       Does nothing, but could eventually restore old palette.
  404.  
  405. void read_palette(char *buffer)
  406.       Stores the current palette into the given buffer; the buffer must have
  407.       room for either 16 or 256 three-byte entries.
  408.  
  409. int user_poly_color(POLY *p, int pcolor)
  410.       Does the mapping of user-specified color values into whatever format
  411.       gets passed to lower-level drawing routines; this is where cosine
  412.       lighting is done, for example.
  413.  
  414. These routines may be changed at will, but bear in mind that this may make
  415. color usage incompatable with data files generated elsewhere.
  416.  
  417. SECTION G -- RENDERING ROUTINES
  418.  
  419. These routines are the main interface to the renderer.
  420.  
  421. void setup_render()
  422.       Sets up the internal data structures used by the renderer; should be
  423.       called before doing any other calls to any of the rend386 library
  424.       routines.
  425.  
  426. void reset_render()
  427.       Frees memory allocated for internal data structures used by the renderer;
  428.       should be called before exiting.
  429.  
  430. void render(OBJLIST *objlist, VIEW *view)
  431.       Renders all the objects in the given objlist from the given viewpoint,
  432.       writing to the current page (see set_drawpage()).
  433.  
  434. This next routine can be called by the user part of the renderer code.
  435.  
  436. int poly_cosine(void *poly)
  437.       Given a pointer to a polygon, returns the cosine of the angle between
  438.       the current light source and the polygon's surface normal; the value
  439.       returned is actually the cosine times 128.
  440.  
  441. SECTION H -- ROUTINES CALLED BY THE RENDERER
  442.  
  443. These routines are provided by the user (source in render.c); you can implement
  444. your own "back end" to the renderer just by rewriting these routines.
  445.  
  446. void ppoly(int count, int *xcoords, int *ycoords, int color)
  447.       Given an array of x coordinates, an array of y coordinates, a count of the
  448.       number of such coordinate pairs, and a color, this routine will display
  449.       the polygon on the screen.
  450.  
  451. void user_setup_blitter()
  452.       Sets up the blitter.
  453.  
  454. void user_reset_blitter()
  455.       Resets the blitter.
  456.  
  457. void user_box(int x1, int y1, int x2, int y2, int color)
  458.       Draws a box with top left corner (x1,y1) and bottom right corner (x2,y2)
  459.       filled in the given color.
  460.  
  461. void user_text(int x, int y, int color, char *string)
  462.       Displays a string at (x,y) in the given color.
  463.  
  464. void user_render_poly(int number, int *xcoords, int *ycoords, int color)
  465.       Similar to ppoly, but at a higher level; lets you intercept calls and
  466.       add features.  See render.c for details.
  467.  
  468. There is also a global flag, an integer called 'wireframe', which, if non-zero,
  469. will cause all objects to be rendered in wireframe mode.  Note that this is
  470. in general slower than actual filled-polygon rendering, since the absence of
  471. explicit edge information forces each edge to be drawn twice.
  472.  
  473. SECTION I -- MISCELLANEOUS ROUTINES
  474.  
  475. OBJECT *where_screen_pt(int *pol, int *vert, int x, int y)
  476.       Given the x, y location of a point on the screen this routine returns a
  477.       pointer to the object that point is on; if pol is not NULL, it is
  478.       set to be the index in the object of the polygon the cursor is on, and
  479.       if vert is not NULL, it is set to the index of the vertex in the object
  480.       that is nearest to the given point.
  481.  
  482. SECTION J -- LOWER-LEVEL GRAPHICS ROUTINES
  483.  
  484. enter_graphics()
  485.       Enter graphics mode.
  486.  
  487. exit_graphics()
  488.        Exit graphics mode.
  489.  
  490. void clear_display(int page)
  491.        Clear the given display page.
  492.  
  493. int set_drawpage(int page)
  494.        Make the given page the 'active' one for drawing.
  495.  
  496. int set_vidpage(int page, int wait)
  497.        Make the given page the 'visible' one.
  498.  
  499. void vgabox(int left, int top, int right, int bottom, int color)
  500.        Draw a box on the display at the given location in the given color.
  501.  
  502. SECTION K -- MOUSE ROUTINES
  503.  
  504. These routines all go through the mouse driver for reading the mouse position,
  505. but draw their own cursor (in order to support mode Y graphics).
  506.  
  507. int mouse_init()
  508.         Initializes the mouse, returns non-zero if one is present.
  509.  
  510. void mouse_deinit()
  511.         De-initializes the mouse.
  512.  
  513. int mouse_read(int *x, int *y, unsigned *buttons)
  514.         Reads the current screen position of the mouse into *x and *y, and the
  515.         current button state into *buttons; returns non-zero if the mouse or
  516.         its buttons have changed since the last call.
  517.  
  518. int mouse_hide()
  519.         Hides the mouse and decrements the mouse flag.
  520.  
  521. void mouse_show(int page)
  522.         Increments the mouse flag, and displays the cursor if the resulting
  523.         value is zero.
  524.  
  525. SECTION L -- JOYSTICK ROUTINES
  526.  
  527. The package provides support for reading a joystick.  The following struct
  528. describes the information associated with a joystick port:
  529.  
  530. typedef struct { 
  531.     int x, y, buttons;
  532.     int cenx, ceny;
  533.     int xrange, yrange;
  534.     long scale;
  535.     int port;  /* port number, 0 or 1; -1 means 'unused' */
  536.     } joystick_data;
  537.  
  538. The x, y and buttons fields are the values read from the joystick.  The
  539. cenx and ceny values are the values of x and y that are read when the joystick
  540. is centered; the values the application program sees are relative to these
  541. center values, so (0,0) is a centered stick.
  542.  
  543. The xrange and yrange values are the maximum values for x and y; the scale
  544. factor is the ratio of movement on the screen to movement of the joystick.
  545.  
  546. The value the user sees after a call to joystick_read() is, in the case of
  547. x, ((x_as_read - cenx) * scale)/xrange.
  548.  
  549. The port value specifies which of the two possible joysticks this structure
  550. corresponds to.
  551.  
  552. int joystick_check()
  553.        Checks for the presence of one or two joysticks; the returned value has
  554.        the low-order bit set if joystick 1 is present, and the next higher bit
  555.        set if joystick 2 is present.
  556.  
  557. void joystick_init(joystick_data *joy, int port)
  558.        Initializes the joystick on the given port (0 or 1)
  559.  
  560. void joystick_setscale(joystick_data *joy, int value)
  561.        Sets the scale factor for the given joystick
  562.  
  563. void joystick_scale(joystick_data *joy, int dir)
  564.        Used for joystick calibration; should be called with dir = 0 and joystick
  565.        forward and to the left, then again with dir = 1 and joystick backward and
  566.        to the right.  This sets the xrange and yrange values for you.
  567.  
  568. int joystick_read(joystick_data *joystick)
  569.        Reads the current values of the specified joystick.
  570.  
  571. void joystick_quit()
  572.        De-initializes joystick processing (current does nothing)
  573.  
  574. SECTION M -- POINTER ROUTINES
  575.  
  576. Primitive support is provided for 3-dimensional pointing devices.  The file
  577. pointer.c contains a set of routines that map the movement of a standard
  578. mouse into three-space; horizontal is X, vertical is Y, and vertical with the
  579. right-hand button down is Z.  If you have a "real" 3D pointing device (e.g.
  580. PowerGlove) you can rewrite the routines in pointer.c to make use of it.
  581.  
  582. The following structure is used to return information about the 3D pointer:
  583.  
  584. typedef struct {
  585.     long x, y, z;          /* location in world coordinates */
  586.     long pan, tilt, roll;  /* orientation around x, y, z */
  587.     unsigned buttons;      /* 16 bits */
  588.     unsigned gesture;      /* for future expansion */
  589.     int port;              /* in case we need this */
  590.     long sx, sy, sz;       /* scaling factors */
  591.     int flex[16];          /* up to 16 words of flexion information */
  592.     } POINTER;
  593.  
  594. The x, y and z values are the location of the pointer in world coordinates.
  595. The pan, tilt and roll are the rotation of the pointer in 16.16 format.
  596. The buttons represent up to 16 buttons, each of which is down or up; in the
  597. case of the powerglove, this may correspond to one byte of finger information
  598. and one byte of button information (for example).
  599.  
  600. The port value is used in case multiple 3D pointing devices are available.
  601.  
  602. The scaling values are used to alter the movement of the pointer relative
  603. to that of the pointing device.
  604.  
  605. The 16 words of flexion information are provided for devices that provide
  606. more detailed information about joint angles; the gesture field is provided
  607. for those systems that support gesture recognition.
  608.  
  609. pointer_init(int port, POINTER *pointer)
  610.       Initializes the pointing device on the given port; returns non-zero if
  611.       a device is found, zero otherwise.
  612.  
  613. pointer_read(POINTER *pointer)
  614.       Reads the given pointer, updating the fields in the given struct, and
  615.       returning non-zero if the pointer has changed state (location,
  616.       orientation or buttons) since the last call to pointer_read().
  617.  
  618. void pointer_scale(POINTER *pointer, long sx, long sy, long sz)
  619.       Sets the scaling for the pointer x, y, and z values.
  620.  
  621. void pointer_quit(POINTER *pointer)
  622.       De-initializes the given pointing device.
  623.  
  624. void pointer_move(POINTER *pointer, long x, long y, long z)
  625.       Sets the current position of the pointer in world coordinates; all
  626.       subsequent movements of the pointing device will be relative to this
  627.       position.
  628.  
  629. SECTION N -- USER-INTERFACE ROUTINES
  630.  
  631. These routines allow you to provide a simple user interface.
  632.  
  633. void neatbox(int w, int h, int *x, int *y)
  634.         Displays a neat-looking box of height h and width w, centered on the
  635.         screen.  The *x and *y values are set to the computed top-left corner
  636.         of the box.
  637.  
  638. void poptext(char *text[])
  639.         Pops up text box on the screen; the 'text' parameter is an array of
  640.         strings, the last of which is NULL.
  641.  
  642. void popmsg(char *msg)
  643.         Pops up a one-line message in a box centered on the screen
  644.  
  645. unsigned askfor(char *prompt, char *buff, int n)
  646.         Prompts the user to enter a string; buff must contain room for up to n
  647.         characters plus a null byte to terminate the string.
  648.  
  649. SECTION O -- PLG FILE I/O ROUTINES
  650.  
  651. The ".plg" file format is described in plg.doc; it is not tightly coupled to
  652. the rest of the renderer software.
  653.  
  654. OBJECT *load_plg(FILE *in)
  655.       Loads a .plg file and returns a pointer to the newly-created OBJECT.
  656.       The global variable load_err will be set to a non-zero value if there
  657.       was a problem loading the file.  As the file is loaded, it is first
  658.       scaled by the current scaling factor and then shifted by the current
  659.       x,y,z offset.
  660.  
  661. void set_loadplg_offset(long x, long y, long z)
  662.       Specifies the x,y,z offset to use; see figure.doc for details.
  663.     
  664. void set_loadplg_scale(float x, float y, float z)
  665.       Specifies the x,y,z scaling to use; see figure.doc for details.
  666.  
  667. save_plg(OBJECT *obj, FILE *out)
  668.       Saves the given object as a .plg file.
  669.  
  670. SECTION P -- FIG FILE I/O ROUTINES
  671.  
  672. A figure file consists of a set of segments.  See figure.doc for details.
  673. The format of a figure file is not tightly coupled to the rest of the
  674. renderer.
  675.  
  676. SEGMENT *readseg(FILE *in, SEGMENT *parent)
  677.      Allocates a new segment, with the given parent, and reads a segment
  678.      description into that segment.  If the file contains nested segments,
  679.      readseg will recursively call itself to load them.  See figure.doc for
  680.      more information.  The global integer variable readseg_err will be set
  681.      to a non-zero value if an error was encountered during loading.
  682.  
  683. void set_readseg_objlist(OBJLIST *objlist)
  684.      Sets the given object list as the one to add newly-loaded representations
  685.      to.
  686.  
  687. writeseg(FILE *out, SEGMENT *s, int level)
  688.      Writes the given segment out to a file; 'level' is used to provide
  689.      levels of indentation, since writeseg calls itself recursively.  In
  690.      general, root segments should be written out with level = 0.
  691.  
  692. SECTION Q -- PCX FILE I/O ROUTINES
  693.  
  694. These routines are only available in 256 color mode, and allow you to read
  695. and write .PCX files (PC-Paintbrush format).
  696.  
  697. load_pcx(FILE *in, int page)
  698.        Load a 320x200x256 .PCX image from the given file onto the given
  699.        display page.
  700.  
  701. int save_pcx(FILE *out, int page)
  702.        Save a 320x200x256 .PCX image into the given file from the given
  703.        display page.
  704.  
  705. THE FUTURE:
  706.  
  707. This rendering package is intended to be the foundation for a wide range
  708. of applications.  Further developments will include replacing the polygon
  709. blitter with a scan-line based routine; this will not have much effect on
  710. the speed, but will eliminate the occasional rendering errors that the
  711. present Z-depth sorting approach can produce.
  712.  
  713. For further information about the package, feel free to contact us:
  714.  
  715.     Bernie Roehl (broehl@sunee.waterloo.edu)
  716.     Dave Stampe (dstampe@sunee.waterloo.edu)
  717.  
  718. Note that at some point in the future, sunee.waterloo.edu will become
  719. sunee.uwaterloo.ca (the ".ca" stands for CAnada, not CAlifornia!)
  720.  
  721. The major contribution others can make to the project at this stage is
  722. to write converters from other polygon formats to OFF.  In particular,
  723. a DXF to OFF converter would let us create objects with a CAD package.
  724.  
  725. OFF is a reasonably good, open format that encodes author/copyright
  726. information along with geometry and colors.  While it's a bit of a
  727. nuisance to parse, it's very easy to generate.
  728.  
  729. Two of our data files were converted from OFF files using off2plg: the bishop
  730. and the banana.  Below is the author/copyright information from their .aoff
  731. files:
  732.  
  733. name        bishop8
  734. description    chess piece - bishop
  735. author        Randy Brown, brown@cs.unc.edu
  736. copyright    (c) Randy Brown, OK to distribute if copyright/author appears 
  737.  
  738. name        banana
  739. description    Banana made on Frank Crow's U. Utah surface design system
  740. copyright    (c) Ohio State Univ. - ok to distribute if copyright appears
  741.  
  742. That's it.  Please direct any questions to broehl@sunee.waterloo.edu or
  743. dstamp@serv1.waterloo.edu, or join the mailing list.  To join the list,
  744. send mail to rend386-request@sunee.uwaterloo.ca (the list itself is just
  745. rend386@sunee.uwaterloo.ca).
  746.  
  747.